package com.pilipala.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pilipala.constant.LikesConstant;
import com.pilipala.constant.MessageConstant;
import com.pilipala.constant.SearchConstant;
import com.pilipala.constant.UploadConstant;
import com.pilipala.context.BaseContext;
import com.pilipala.dto.*;
import com.pilipala.entity.Blog;
import com.pilipala.entity.User;
import com.pilipala.entity.Video;
import com.pilipala.exception.DeleteException;
import com.pilipala.exception.OrderException;
import com.pilipala.exception.UpdateException;
import com.pilipala.exception.UploadException;
import com.pilipala.mapper.UserMapper;
import com.pilipala.mapper.VideoMapper;
import com.pilipala.result.PageResult;
import com.pilipala.service.VideoService;
import com.pilipala.utils.AliOssUtil;
import com.pilipala.vo.UserVO;
import com.pilipala.vo.VideoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VideoServiceImpl implements VideoService {

    @Autowired
    private AliOssUtil aliOssUtil;

    @Autowired
    private VideoMapper videoMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<String,Long> redisTemplate;
    /**
     * 上传封面
     * @param file 上传的文件
     * @return 返回拼装的封面路径
     */
    @Override
    public String uploadCover(MultipartFile file) {
//        正常情况下不应该为空
        if (file.getOriginalFilename() == null){
            throw new UploadException(MessageConstant.UPLOAD_FAIL);
        }
        String fileUrl;
        try {
            String filename = file.getOriginalFilename();
//        获取到后缀名
            String extension = filename.substring(filename.lastIndexOf("."));
//            文件格式不支持
            if (!extension.contains("png")&&!extension.contains("jpg")&&!extension.contains("jpeg")){
                throw new UploadException(MessageConstant.UPLOAD_FORMAT);
            }
//        文件名称
            String objectName =  UploadConstant.COVER_PRE+ UUID.randomUUID() + extension;
            fileUrl = aliOssUtil.upload(file.getBytes(), objectName);
        }
        catch (IOException exception){
            throw new UploadException(MessageConstant.UPLOAD_FAIL);
        }
        return fileUrl;
    }

    /**
     * 上传视频
     * @param file 上传的文件
     * @return 返回拼装的路径
     */
    @Override
    public String uploadVideo(MultipartFile file) {
        //        正常情况下不应该为空
        if (file.getOriginalFilename() == null){
            throw new UploadException(MessageConstant.UPLOAD_FAIL);
        }
        String fileUrl;
        String filename = UploadConstant.VIDEO_PRE + file.getOriginalFilename();
//        获取到后缀名
        String extension = filename.substring(filename.lastIndexOf("."));
//            文件格式不支持
        if (!extension.contains(UploadConstant.VIDEO_EXTENSION)){
            throw new UploadException(MessageConstant.UPLOAD_FORMAT);
        }
//        文件名称
        String objectName = UUID.randomUUID() + extension;
        fileUrl = aliOssUtil.uploadLargeFile(objectName,file);
        return fileUrl;
    }

    /**
     * 新增视频字段
     * @param videoDTO 视频的所有字段
     */
    @Override
    public void create(VideoDTO videoDTO) {
        User user = userMapper.getUserById(BaseContext.getCurrentId());

//        设置视频数据
        Video video = new Video();
        BeanUtils.copyProperties(videoDTO,video);
        video.setUserId(BaseContext.getCurrentId());
        video.setUserName(user.getUserName());
        video.setUploadTime(new Date());


        log.info("videoDTO的数据:{}",videoDTO);
        log.info("video的数据:{}",video);
        videoMapper.insert(video);
    }


    /**
     * 根据用户Id获取视频
     * @param videoPageDTO 用户Id
     * @return 分页后的视频数据
     */
    public PageResult getByUserId(VideoPageDTO videoPageDTO) {
        PageHelper.startPage(videoPageDTO.getPage(),videoPageDTO.getPageSize());
        Page<Video> page = videoMapper.pageQuery(videoPageDTO);
//        获取到有多少数据
        long total = page.getTotal();
        List<Video> result = page.getResult();

        page.close();
        PageHelper.clearPage();
//        设置返回数据
        return new PageResult(total,result);
    }

    @Override
    public PageResult listAll(VideoPageDTO videoPageDTO) {
        PageHelper.startPage(videoPageDTO.getPage(),videoPageDTO.getPageSize());
        Page<Video> page = videoMapper.listAll();
        long total = page.getTotal();
        List<Video> pageResult = page.getResult();
        page.close();
        return new PageResult(total,pageResult);
    }

    /**
     * 关于video的搜索接口
     * @param searchDTO 包括页码、页大小、搜索关键字、排序类型
     * @return 返回分页后的video
     */
    @Override
    public PageResult search(SearchDTO searchDTO) {
        if (!SearchConstant.ORDERLIST.contains(searchDTO.getOrder())){
            throw new OrderException(MessageConstant.ORDER_TYPE_ERROR);
        }

        if (Objects.equals(searchDTO.getOrder(), "time")){
            searchDTO.setOrder("upload_time");
        }
        PageHelper.startPage(searchDTO.getPage(),searchDTO.getPageSize());
        log.info("查询条件：{}",searchDTO);
        Page<Video> page = videoMapper.search(searchDTO);

        long total = page.getTotal();
        List<Video> pageResult = page.getResult();

        page.close();
        PageHelper.clearPage();
        return new PageResult(total,pageResult);
    }

    @Override
    public VideoVO getById(Long id) {
//        根据video的Id获取video
        Video video = videoMapper.getById(id);
//        封装videoVO
        VideoVO videoVO = new VideoVO();
        BeanUtils.copyProperties(video,videoVO);
//        查询是否有收藏
        Long userId = BaseContext.getCurrentId();
        Long favoritesId = videoMapper.getFavoritesPair(id,userId);
        videoVO.setCollectionId(favoritesId);

//        查询是否有点赞
        Boolean isLike = redisTemplate.opsForSet().isMember(LikesConstant.VIDEO_PRE + id, BaseContext.getCurrentId());
        videoVO.setIsLike(isLike);
        return videoVO;
    }

    /**
     * 根据视频Id删除视频
     * @param id 视频Id
     */
    @Override
    public void delete(Long id) {
        Long userId = BaseContext.getCurrentId();
        Video video = videoMapper.getById(id);
        if (!video.getUserId().equals(userId)){
//        不是本人不能删除
            throw new DeleteException(MessageConstant.POWER_ERROR);
        }
        videoMapper.delete(id);
    }

    @Override
    public void update(VideoDTO videoDTO) {
//        复制信息
        Video video = videoMapper.getById(videoDTO.getId());
        if (!Objects.equals(video.getUserId(), BaseContext.getCurrentId())){
//            只有本人可以修改视频信息
            throw new UpdateException(MessageConstant.POWER_ERROR);
        }
        Video videoTmp = new Video();
        BeanUtils.copyProperties(videoDTO,videoTmp);

        videoTmp.setUploadTime(new Date());
        videoMapper.update(videoTmp);
    }


    /**
     * 收藏视频
     * @param videoId 视频Id
     */
    @Override
    public void collection(Long videoId) {
        Long userId = BaseContext.getCurrentId();
        Long collectionId = videoMapper.getFavoritesPair(videoId, userId);
        if (collectionId == null){
//            如果没有关注，那就是关注事件
            videoMapper.addCollection(videoId,userId);
            Video video = videoMapper.getById(videoId);
            video.setCollectionNumber(video.getCollectionNumber() + 1);

            videoMapper.update(video);
        }else{
//            查得到说明是要取消关注
            videoMapper.deleteCollection(videoId,userId);
            Video video = videoMapper.getById(videoId);
            video.setCollectionNumber(video.getCollectionNumber() - 1);

            videoMapper.update(video);
        }
    }

    @Override
    public PageResult getCollection(PageinationDTO pageinationDTO) {
        PageHelper.startPage(pageinationDTO.getCurrent(),pageinationDTO.getPageSize());
        Page<Long> page = videoMapper.getCollectionByUserId(BaseContext.getCurrentId());
//        获取所有的video_id
        long total = page.getTotal();
        List<Video> videoList = new ArrayList<>();
        for (var videoId : page.getResult()){
            if (videoId == null){
                continue;
            }
            Video video = videoMapper.getById(videoId);
            videoList.add(video);
        }
        return new PageResult(videoList.size(),videoList);
    }

    /**
     * TODO 点赞视频
     * @param videoId 视频id
     */
    @Override
    public void likes(Long videoId) {
        Boolean isLikes = redisTemplate.opsForSet().isMember(LikesConstant.VIDEO_PRE + videoId, BaseContext.getCurrentId());
        Video video = videoMapper.getById(videoId);
        if (Boolean.TRUE.equals(isLikes)){
//            如果已经点赞过了
            redisTemplate.opsForSet().remove(LikesConstant.VIDEO_PRE+videoId,BaseContext.getCurrentId());
            video.setLikes(video.getLikes() - 1);
        }else{
//            没点赞过
            redisTemplate.opsForSet().add(LikesConstant.VIDEO_PRE+videoId,BaseContext.getCurrentId());
            redisTemplate.expire(LikesConstant.VIDEO_PRE+videoId,LikesConstant.TTL, TimeUnit.DAYS);
            video.setLikes(video.getLikes() + 1);
        }
        videoMapper.update(video);
    }
}




